package util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * //                       .::::.
 * //                     .::::::::.
 * //                    :::::::::::
 * //                 ..:::::::::::'
 * //              '::::::::::::'
 * //                .::::::::::
 * //           '::::::::::::::..
 * //                ..::::::::::::.
 * //              ``::::::::::::::::
 * //               ::::``:::::::::'        .:::.
 * //              ::::'   ':::::'       .::::::::.
 * //            .::::'      ::::     .:::::::'::::.
 * //           .:::'       :::::  .:::::::::' ':::::.
 * //          .::'        :::::.:::::::::'      ':::::.
 * //         .::'         ::::::::::::::'         ``::::.
 * //     ...:::           ::::::::::::'              ``::.
 * //    ```` ':.          ':::::::::'                  ::::..
 * //                       '.:::::'                    ':'````..
 *
 * @author 华韵流风
 * @ClassName DruidPool
 * @Description TODO
 * @Date 2021/5/7 14:46
 * @packageName util
 */
public class DruidPool {

    private static ThreadLocal<Connection> tl = new ThreadLocal<>();

    //饿汉式，单例模式
    private static final DruidDataSource pool = new DruidDataSource();

    //静态代码快，保证连接池对象在类加载过程中就完成初始化
    static {
        //对象连接池进行初始化，设置一些必须的参数，这些参数从外部文件中获取
        Properties pt = new Properties();//创建属性集合对象

        //把外部参数加载到该对象中
        InputStream inputStream = DruidPool.class.getClassLoader().getResourceAsStream("db.properties");
        try {
            pt.load(inputStream);//利用字节输入流对象完成参数的加载
            //从集合中取出各参数，并设置连接池
            pool.setDriverClassName(pt.getProperty("driverName"));
            pool.setUrl(pt.getProperty("url"));
            pool.setUsername(pt.getProperty("user"));
            pool.setPassword(pt.getProperty("password"));
            //以上四个为必须要有的
            pool.setInitialSize(Integer.parseInt(pt.getProperty("InitialSize")));
            pool.setMinIdle(Integer.parseInt(pt.getProperty("MinIdle")));
            pool.setMaxActive(Integer.parseInt(pt.getProperty("MaxActive")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //该方法返回一个连接对象给线程，并保证同一线程中只有一个连接对象
    public static Connection getConnection() throws SQLException {
        DruidPooledConnection connection = null;
        System.out.println(Thread.currentThread().getName() + " 当前的连接数量：" + pool.getActiveCount() + " 当前空闲的连接数量：" + pool.getPoolingCount());
        if (tl.get() == null) {
            try {
                connection = pool.getConnection();
                //把连接对象放到ThreadLocal变量中，保证线程在各个方法中都可以使用
                tl.set(connection);
            } catch (SQLException sqlException) {
                sqlException.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " 当前的连接数量：" + pool.getActiveCount() + " 当前空闲的连接数量：" + pool.getPoolingCount());
            return connection;
        } else {
            return tl.get();
            //throw new SQLException("本线程已有连接对象！");
        }
    }

    //释放连接
    public static void releaseConnection() {
        if (tl.get() != null) {
            try {
                tl.get().close();
                tl.remove();
            } catch (SQLException sqlException) {
                sqlException.printStackTrace();
            }
        }
    }


}
